package com.inspiration.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.inspiration.dao.CategoryContentRelationMapper;
import com.inspiration.dao.ContentMapper;
import com.inspiration.dao.TagContentRelationMapper;
import com.inspiration.entity.Category;
import com.inspiration.entity.CategoryContentRelation;
import com.inspiration.entity.Content;
import com.inspiration.entity.R;
import com.inspiration.entity.Tag;
import com.inspiration.entity.TagContentRelation;
import com.inspiration.entity.dto.ContentDTO;
import com.inspiration.entity.dto.SearchContentDTO;
import com.inspiration.entity.vo.ContentVO;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.NumberToTextConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description
 * @Author Vincent.jiao
 * @Date 2023/11/16 11:07
 */
@Service
public class ContentService {
    @Autowired
    TagContentRelationMapper tagContentRelationMapper;

    @Autowired
    CategoryContentRelationMapper categoryContentRelationMapper;

    @Autowired
    CategoryService categoryService;

    @Autowired
    TagService tagService;

    @Autowired
    ContentMapper contentMapper;

    @Transactional
    public boolean update(Content content ){
        return  contentMapper.updateById(content) > 0;
    }

    @Transactional
    public Object del(Long cId    ) {
        delRelation(cId);
        contentMapper.deleteById(cId);

        return "ok";
    }

    @Transactional
    public void delRelation(Long cId    ) {
        tagContentRelationMapper.delete(new LambdaUpdateWrapper<TagContentRelation>()
                .eq(TagContentRelation::getTcr_c_id, cId));

        categoryContentRelationMapper.delete(new LambdaUpdateWrapper<CategoryContentRelation>()
                .eq(CategoryContentRelation::getCcr_content_id, cId));
    }

    @Transactional
    public Object writeContent(ContentDTO contentDTO) {
        if(contentDTO == null || StrUtil.isEmpty(contentDTO.getC_name())) {
            return false;
        }

        if(contentDTO.getC_id() != null && contentDTO.getC_id() > 0) {
            delRelation(contentDTO.getC_id());
        }

        Content content = new Content();
        BeanUtil.copyProperties(contentDTO, content);
        content.setC_name(content.getC_name().trim());

        if(StrUtil.isNotEmpty(content.getC_desc())) {
            content.setC_desc(content.getC_desc().trim());
        }
        if(contentDTO.getC_id() != null && contentDTO.getC_id() > 0) {
            update(content);
        } else {
            insert(content);
        }

        //插入tag
        if(CollUtil.isNotEmpty(contentDTO.getTagList())) {
            for (Long item : contentDTO.getTagList()) {
                TagContentRelation relation = new TagContentRelation();
                relation.setTcr_t_id(item);
                relation.setTcr_c_id(content.getC_id());

                tagContentRelationMapper.insert(relation);
            }
        }

        //插入分类
        if(CollUtil.isNotEmpty(contentDTO.getCategoryList())) {
            for (Long item : contentDTO.getCategoryList()) {
                CategoryContentRelation relation = new CategoryContentRelation();
                relation.setCcr_content_id(content.getC_id());
                relation.setCcr_category_id(item);

                categoryContentRelationMapper.insert(relation);
            }
        }

        return "ok";
    }

    @Transactional
    public boolean insert(Content content ){
        return  contentMapper.insert(content) > 0;
    }

    public int count() {
        return contentMapper.selectCount(new LambdaQueryWrapper<>());
    }

    public Content getById( long id){
        return contentMapper.selectOne(new LambdaQueryWrapper<Content>().eq(Content::getC_id, id));
    }

    public List listBySearchContentDTO(SearchContentDTO contentDTO) {
        return contentMapper.listBySearchContentDTO(contentDTO);
    }

    public List<ContentVO> listDetailsVO(List<Long> idList) {
        return contentMapper.listDetailsVO(idList);
    }

    @Transactional
    public Object importExcel(Workbook workbook) {
        List<Boolean> resultList = new LinkedList<>();
        Sheet sheet = workbook.getSheetAt(0);
        List<List<String>> excelList = new LinkedList<>();
        List<String> rowList = null;

        for (int i = 0; i <= sheet.getLastRowNum(); i++) {
            Row row = sheet.getRow(i);

            if(i == 0) {
                if( !("分类".equals(getCellString(row, 0))
                        &&  "标签".equals(getCellString(row, 1))
                        &&  "内容".equals(getCellString(row, 2))
                        &&  "描述".equals(getCellString(row, 3)))
                ) {
                    return R.ok("errorMsg", "文件不合法");
                }

                continue;
            }

            rowList = new LinkedList<>();
            String val = getCellString(row, 0);
            if(StrUtil.isEmpty(val)) {
                continue;
            }
            rowList.add(val.trim());

            val = getCellString(row, 1);
            rowList.add(val != null ? val.trim() : null);

            val = getCellString(row, 2);
            rowList.add(val != null ? val.trim() : null);

            val = getCellString(row, 3);
            rowList.add(val != null ? val.trim() : null);

            excelList.add(rowList);
        }

        if(CollUtil.isEmpty(excelList)) {
            return R.ok("list", resultList);
        }


        List<Tag> tagList = tagService.list(null);
        Map<String, Long> tagMap = tagList.stream()
                .collect(Collectors.toMap(Tag::getT_name, e -> e.getT_id(), (key1, key2) -> key1));

        List<Category> categoryList = categoryService.list(null);
        List<Long> categoryIdList = categoryList.stream().map(Category::getC_id).collect(Collectors.toList());

        //循环excel
        for (List<String> itemList : excelList) {
            ContentDTO contentDTO = new ContentDTO();

            //过滤掉不存在的分类
            String categroyStr = itemList.get(0).replaceAll("，", ",")
                    .replaceAll("、", ",")
                    .replaceAll(" ", ",") ;
            List<Long> cIdList = new LinkedList<>();
            for (String idStr : categroyStr.split(",")) {
                String name = idStr.trim();
                if(categoryIdList.contains(Long.valueOf(name))) {
                    cIdList.add(Long.valueOf(name));
                }
            }
            contentDTO.setCategoryList(cIdList);

            String tagStr = itemList.get(1);
            List<Long> tagIdList = new LinkedList<>();
            if(StrUtil.isNotEmpty(tagStr)) {
                //支持 、 ， ' ' 分割
                String[] tagNameArr = tagStr.replaceAll("，", ",")
                        .replaceAll("、", ",")
                        .replaceAll(" ", ",")
                        .split(",");
                List<String> insertTagList = new LinkedList<>();
                for (int i = 0; i < tagNameArr.length; i++) {
                    String name = tagNameArr[i].trim();
                    if(!tagMap.containsKey(name)) {
                        insertTagList.add(name);
                    }
                }
                //插入标签
                for (String item : insertTagList) {
                    Tag tag = new Tag();
                    tag.setT_name(item);
                    tag.setT_desc(item);

                    boolean flag = tagService.insert(tag);
                    if(flag) {
                        tagMap.put(tag.getT_name(), tag.getT_id());
                    }
                }

                for (String item : tagNameArr) {
                    tagIdList.add(tagMap.get(item));
                }
            }

            contentDTO.setTagList(tagIdList);
            contentDTO.setC_name(itemList.get(2));
            contentDTO.setC_desc(itemList.get(3));

            boolean flag = false;
            flag = "ok".equals(writeContent(contentDTO));
            resultList.add(flag);
        }

        return R.ok("list", resultList);
    }

    public String getCellString(Row row, int i) {
        return getCellValue(row.getCell(i));
    }

    public String getCellValue(Cell cell) {
        String ret = null;
        if(cell == null) {
            return ret;
        }

        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_BLANK:
                ret = "";
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                ret = String.valueOf(cell.getBooleanCellValue());
                break;
            case Cell.CELL_TYPE_ERROR:
                ret = null;
                break;
            case Cell.CELL_TYPE_NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    //ret =String.valueOf(cell.getDateCellValue().getTime());
                    DateFormat formater = new SimpleDateFormat("yyyy/MM/dd");
                    ret = formater.format(cell.getDateCellValue().getTime());
                } else {
                    //如果日期只输入了一串数字，那么就是格式错误
//                    if(index == 5 || index == 12 || index == 13){
//                        ret = "dateformaterror";
//                        break;
//                    }
                    ret = NumberToTextConverter.toText(cell.getNumericCellValue());
                }
                break;
            case Cell.CELL_TYPE_STRING:
                ret = cell.getRichStringCellValue().getString();
                break;
            default:
                ret = null;
        }

        return ret;
    }
}
